package com.knowledge.business.service.impl;

import com.knowledge.business.domain.*;
import com.knowledge.business.mapper.SysMessageMapper;
import com.knowledge.business.service.IMessageStatService;
import com.knowledge.business.service.JnISysRoleService;
import com.knowledge.business.util.MessageSimilarityUtil;
import com.knowledge.common.utils.DateUtils;
import com.knowledge.common.utils.PageUtils;
import com.knowledge.common.utils.StringUtils;
import com.knowledge.system.service.impl.SysRoleServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 消息统计服务实现类
 *
 * @author lingma
 * @date 2025-09-26
 */
@Service
public class MessageStatServiceImpl implements IMessageStatService {

    @Autowired
    private SysMessageMapper sysMessageMapper;


    @Autowired
    private JnISysRoleService sysRoleService;

    /**
     * 基于相似度分析获取热门消息
     *
     * @param days                天数范围
     * @param limit               返回记录数
     * @param similarityThreshold 相似度阈值，超过此值认为是相似消息
     * @return 热门消息列表
     */
//    @Override
//    public List<HotMessageDTO> getHotMessagesBySimilarity(int days, int limit, double similarityThreshold) {
//        // 从数据库获取指定天数内的消息数据
//        List<MessageWithTime> messages = sysMessageMapper.selectMessagesWithTimeByDays(days);
//
//        // 按相似度分组消息
//        List<MessageGroup> groups = groupMessagesBySimilarity(messages, similarityThreshold);
//
//        // 转换为热门消息DTO列表
//        List<HotMessageDTO> hotMessages = new ArrayList<>();
//        for (MessageGroup group : groups) {
//            HotMessageDTO dto = new HotMessageDTO();
//            dto.setMessage(group.getRepresentativeMessage());
//            dto.setCount(group.getCount());
//            dto.setLastTime(group.getLastTime());
//            dto.setSimilarCount(group.getMessages().size());
//            hotMessages.add(dto);
//        }
//
//        // 按热度排序
//        hotMessages.sort((a, b) -> {
//            // 首先按数量排序
//            int countCompare = b.getCount().compareTo(a.getCount());
//            if (countCompare != 0) {
//                return countCompare;
//            }
//            // 数量相同时按时间排序
//            return b.getLastTime().compareTo(a.getLastTime());
//        });
//
//        // 限制返回数量
//        return hotMessages.size() > limit ? hotMessages.subList(0, limit) : hotMessages;
//    }

    /**
     * 基于相似度分析获取热门消息（支持时间段查询）
     *
     * @return 热门消息列表
     */
    @Override
    public List<SysMessage> getHotMessagesBySimilarity(FxDTO dto) {
        String roleId = dto.getRoleId();
        String startTime = dto.getStartTime();
        String endTime = dto.getEndTime();
        String dzStatus = dto.getDzStatus();
        Integer days = dto.getDays();
        if (days == null) {
            dto.setDays(7);
            days = 7;
        }
//        Double similarityThreshold = dto.getSimilarityThreshold();
//        if (similarityThreshold == null) {
//            dto.setSimilarityThreshold(0.8);
//            similarityThreshold = 0.8;
//        }
        List<String> documentTypeList = new ArrayList<>();
        if (StringUtils.isNotEmpty(roleId)) {
            JnSysRole role = sysRoleService.selectSysRoleByRoleId(roleId);
            String documentType = role.getDocumentType();
            if (StringUtils.isNotEmpty(documentType)) {
                documentTypeList = Arrays.asList(documentType.split(","));
            }
        }
        if (StringUtils.isEmpty(dzStatus)) {
            // 热门问题
            PageUtils.startPage();
            List<SysMessage> sysMessages = sysMessageMapper.selectMessagesHot(dto);
            return sysMessages;
        } else {
            PageUtils.startPage();
            List<SysMessage> messages = sysMessageMapper.selectMessagesWithTimeByDays(dto);
            return messages;
        }
    }

    /**
     * 将消息按相似度分组
     *
     * @param messages            消息列表
     * @param similarityThreshold 相似度阈值
     * @return 消息分组列表
     */

    public List<MessageGroup> groupMessagesBySimilarity(List<MessageWithTime> messages, double similarityThreshold) {
        List<MessageGroup> groups = new ArrayList<>();

        for (MessageWithTime messageWithTime : messages) {
            String message = messageWithTime.getMessage();
            Date createTime = messageWithTime.getCreateTime();

            if (StringUtils.isEmpty(message)) {
                continue;
            }

            // 寻找相似的组
            MessageGroup similarGroup = findSimilarGroup(message, groups, similarityThreshold);

            if (similarGroup != null) {
                // 添加到相似组
                similarGroup.addMessage(message);
                // 更新最后时间，取最新的时间
                if (similarGroup.getLastTime() == null || createTime.after(similarGroup.getLastTime())) {
                    similarGroup.setLastTime(createTime);
                }
            } else {
                // 创建新组
                MessageGroup newGroup = new MessageGroup();
                newGroup.setRepresentativeMessage(message);
                newGroup.addMessage(message);
                newGroup.setLastTime(createTime);
                groups.add(newGroup);
            }
        }

        return groups;
    }

    /**
     * 查找与指定消息相似的组
     *
     * @param message             消息内容
     * @param groups              消息组列表
     * @param similarityThreshold 相似度阈值
     * @return 相似的组，如果不存在则返回null
     */
    private MessageGroup findSimilarGroup(String message, List<MessageGroup> groups, double similarityThreshold) {
        MessageGroup mostSimilarGroup = null;
        double maxSimilarity = similarityThreshold; // 至少要达到阈值

        // 遍历所有组，找到最相似的组
        for (MessageGroup group : groups) {
            // 与组代表消息比较相似度
            double similarity = MessageSimilarityUtil.calculateSimilarity(
                    message, group.getRepresentativeMessage());

            if (similarity >= maxSimilarity) {
                maxSimilarity = similarity;
                mostSimilarGroup = group;
            }
        }

        return mostSimilarGroup;
    }

    /**
     * 获取各时间段消息数量统计
     */
    @Override
    public List<Map<String, Object>> getMessageCountByTimePeriod(FxDTO dto) {
        String startTime = dto.getStartTime();
        String endTime = dto.getEndTime();
        if (StringUtils.isNotEmpty(startTime) && StringUtils.isNotEmpty(endTime)) {
            List<Map<String, Object>> result = new ArrayList<>();
            List<? extends Map<String, Object>> temp = sysMessageMapper.selectMessageCountByTimePeriodWithRange(dto);
            for (Map<String, Object> item : temp) {
                result.add(item);
            }
            return result;
        } else {

            List<Map<String, Object>> result = new ArrayList<>();
            List<? extends Map<String, Object>> temp = sysMessageMapper.selectMessageCountByTimePeriod(dto);
            for (Map<String, Object> item : temp) {
                result.add(item);
            }
            return result;
        }
    }
}
